package com.xxl.job.executor.process;

import com.xxl.job.core.log.XxlJobLogger;
import com.xxl.job.executor.SpringContextUtil;
import com.xxl.job.executor.model.DevInfosModel;
import com.xxl.job.executor.model.GatherDefModel;
import com.xxl.job.executor.model.SignalDefApModel;
import com.xxl.job.executor.model.SignalDefHkModel;
import com.xxl.job.executor.service.AutomaticControlService;
import com.xxl.job.executor.service.GatherDefService;
import com.xxl.job.executor.service.SignalDefService;
import org.snmp4j.*;
import org.snmp4j.mp.MessageProcessingModel;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.smi.GenericAddress;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.OctetString;
import org.snmp4j.transport.DefaultUdpTransportMapping;
import org.snmp4j.util.PDUFactory;
import org.snmp4j.util.TableEvent;
import org.snmp4j.util.TableUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 新华三无线AP采集
 *
 * @author ma.biao
 * @date 2020-08-15
 */
public class H3CApProcess {

    private String param;

    private String ip = "10.0.6.1";

    private String community = "public";


    public H3CApProcess(String param) {
        this.param = param;
    }

    public void collectProcess() throws Exception{
        Date start = new Date();
        try{
            for (int t = 0; t <4000 ; t++) {
                XxlJobLogger.log("*************************************第"+t+"次******************************");
                GatherDefModel gatherDefModel = SpringContextUtil.getBean(GatherDefService.class).getGatherDefModel(param);
                if (gatherDefModel == null) {
                    XxlJobLogger.log("无线AP系统 ：未获取到采集口配置信息");
                    return;
                }

             //   XxlJobLogger.log("--------无线ap采集开始--------");
             //   XxlJobLogger.log("TIME: "+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));

                // 获取h3c已注册mac地址列表
                Map<String, String> macMap = getAtPhysAddress(ip, community);

                // 获取平台无线ap设备mac地址列表
                List<SignalDefHkModel> apSignalList = SpringContextUtil.getBean(SignalDefService.class).queryHkSignalList(
                        gatherDefModel.getGatherId(), gatherDefModel.getResId(), "");

                // 初始化
                List<String> deviceMacs = new ArrayList<>();
                List<String> deviceMacsSub = new ArrayList<>();

                for (int i = 0; i < apSignalList.size(); i++) {
                    if (macMap.containsKey(apSignalList.get(i).getPointAddr())) {
                        deviceMacsSub.add(apSignalList.get(i).getPointAddr());
                    }

                    deviceMacs.add(apSignalList.get(i).getPointAddr());
                }

                deviceMacs.removeAll(deviceMacsSub);


                if (deviceMacs.size() == 0) {
                //    XxlJobLogger.log("--------所有设备均在线--------");
                } else {
                 //   XxlJobLogger.log("--------部分设备离线----------");
//                for(int i=0;i<deviceMacs.size();i++){
//                    System.out.println("离线设备 "+i+"："+deviceMacs.get(i));
//                }
                }
                int flag = 0;
                ArrayList<DevInfosModel> dataDevModelArrayList= new ArrayList<DevInfosModel>();
                // 刷新在线ap数据
                for (int i = 0; i < deviceMacsSub.size(); i++) {
                    SignalDefHkModel apModel = new SignalDefHkModel();
                    apModel.setGatherId(param);
                    apModel.setGatherResId(gatherDefModel.getResId());
                    apModel.setPointAddr(deviceMacsSub.get(i));
                    apModel.setSignalValue("0");

                    if(i==deviceMacsSub.size()-1){
                        flag = 1;
                    }
                    SpringContextUtil.getBean(AutomaticControlService.class).save(apModel, flag,dataDevModelArrayList);
                }


                int flag2 = 0;
                ArrayList<DevInfosModel> dataDevModelArrayList2= new ArrayList<DevInfosModel>();
                // 刷新离线ap数据
                for (int i = 0; i < deviceMacs.size(); i++) {
//                System.out.println("离线设备_" + (i + 1) + "：" +deviceMacs.get(i));
                    SignalDefHkModel apModel = new SignalDefHkModel();
                    apModel.setGatherId(param);
                    apModel.setGatherResId(gatherDefModel.getResId());
                    apModel.setPointAddr(deviceMacs.get(i));
                    apModel.setSignalValue("1");

                    if(i==deviceMacs.size()-1){
                        flag2 = 1;
                    }
                    SpringContextUtil.getBean(AutomaticControlService.class).save(apModel, flag2,dataDevModelArrayList2);
                }

                XxlJobLogger.log("*************************************暂停10秒******************************");
                Thread.sleep(10000);
            }
        }catch(Exception e){
            if (e instanceof InterruptedException) {
                throw e;
            }
            e.printStackTrace();
        }

//        Date end=new Date();
//        float minutes = (float)(end.getTime() - start.getTime()) / (1000 * 60);
//        XxlJobLogger.log("当前程序耗时："+minutes+" 分钟");
    }

    public List<String> getTcpConnectIps(String ip, String community) {
        // 数据汇总list
        List<String> data = new ArrayList<>();
        TransportMapping transport = null;
        Snmp snmp = null;
        CommunityTarget target;
        String[] oids = {".1.3.6.1.2.1.6.13.1.2"}; //tcpConnectLocalAddress h3c当前在线机器ip列表OID地址
        try {
            transport = new DefaultUdpTransportMapping();
            snmp = new Snmp(transport);//创建snmp
            snmp.listen();//监听消息
            target = new CommunityTarget();
            target.setCommunity(new OctetString(community));
            target.setRetries(3);
            target.setAddress(GenericAddress.parse("udp:" + ip + "/161"));
            target.setTimeout(8000);
            target.setVersion(SnmpConstants.version2c);
            TableUtils tableUtils = new TableUtils(snmp, new PDUFactory() {
                @Override
                public PDU createPDU(Target target) {
                    PDU request = new PDU();
                    request.setType(PDU.GET);
                    return request;
                }

                @Override
                public PDU createPDU(MessageProcessingModel messageProcessingModel) {
                    PDU request = new PDU();
                    request.setType(PDU.GET);
                    return request;
                }
            });
            OID[] columns = new OID[oids.length];
            for (int i = 0; i < oids.length; i++)
                columns[i] = new OID(oids[i]);
            List<TableEvent> list = tableUtils.getTable(target, columns, null, null);

            for (int i = 0; i < list.size(); i++) {
                int[] indexValue = list.get(i).getIndex().getValue();
                if (indexValue[0] == 10 && indexValue[1] == 0 && indexValue[2] == 6 && indexValue[3] == 1 &&
                        indexValue[5] == 10 && indexValue[6] == 0 && indexValue[7] == 6) {
                    String ipAddr = indexValue[5] + "." + indexValue[6] + "." + indexValue[7] + "." + indexValue[8];
                    if (!data.contains(ipAddr)) {
                        data.add(ipAddr);
                    }
                }
            }
//            System.out.println("---------------------------------------");
//            System.out.println("ip地址列表：" + data.size());
//            System.out.println("---------------------------------------");
//            System.out.println(data);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (transport != null)
                    transport.close();
                if (snmp != null)
                    snmp.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return data;
    }

    public Map<String, String> getAtPhysAddress(String ip, String community) {
        // 数据汇总list
        Map<String, String> data = new HashMap<>();
        TransportMapping transport = null;
        Snmp snmp = null;
        CommunityTarget target;
        String[] oids = {".1.3.6.1.2.1.3.1.1.2"}; //atPhysAddress h3c当前机器已注册ap的mac地址列表
        try {
            transport = new DefaultUdpTransportMapping();
            snmp = new Snmp(transport);//创建snmp
            snmp.listen();//监听消息
            target = new CommunityTarget();
            target.setCommunity(new OctetString(community));
            target.setRetries(3);
            target.setAddress(GenericAddress.parse("udp:" + ip + "/161"));
            target.setTimeout(8000);
            target.setVersion(SnmpConstants.version2c);
            TableUtils tableUtils = new TableUtils(snmp, new PDUFactory() {
                @Override
                public PDU createPDU(Target target) {
                    PDU request = new PDU();
                    request.setType(PDU.GET);
                    return request;
                }

                @Override
                public PDU createPDU(MessageProcessingModel messageProcessingModel) {
                    PDU request = new PDU();
                    request.setType(PDU.GET);
                    return request;
                }
            });
            OID[] columns = new OID[oids.length];
            for (int i = 0; i < oids.length; i++)
                columns[i] = new OID(oids[i]);
            List<TableEvent> list = tableUtils.getTable(target, columns, null, null);
//            System.out.println("macAddrSize: " + list.size());

            for (int i = 0; i < list.size(); i++) {
                int[] indexValue = list.get(i).getIndex().getValue();
                String ipAddr = indexValue[2] + "." + indexValue[3] + "." + indexValue[4] + "." + indexValue[5];
                data.put(list.get(i).getColumns()[0].getVariable().toString().replace(":", "").toUpperCase(), ipAddr);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (transport != null)
                    transport.close();
                if (snmp != null)
                    snmp.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return data;
    }
}
